package com.lottery.game.core.configuration;

import com.jcraft.jsch.Channel;
import com.jcraft.jsch.ChannelSftp;
import com.jcraft.jsch.JSch;
import com.jcraft.jsch.JSchException;
import com.jcraft.jsch.Session;
import com.jcraft.jsch.SftpException;

import org.apache.commons.net.ftp.FTPSClient;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.context.annotation.PropertySource;
import org.springframework.stereotype.Component;

import java.io.InputStream;
import java.util.Properties;

import lombok.Data;

@Data
@PropertySource("classpath:conf.properties")
@Component
public class SftpUtils {

	// ftp服务器地址
	@Value("${pic.sftp.hostname}")
	public String hostname;

	// ftp服务器端口号默认为22
	@Value("${pic.sftp.port}")
	public Integer port;

	// ftp登录账号
	@Value("${pic.sftp.username}")
	public String username;

	// ftp登录密码
	@Value("${pic.sftp.password}")
	public String password;

	@Value("${pic.sftp.defaultRootPath}")
	public String defaultRootPath;

	@Value("${pic.sftp.appPath}")
	public String appPath;

	public FTPSClient ftpClient = null;

	private ChannelSftp sftp;

	private Session session;

	/**
	 * 连接sftp服务器
	 */
	public void login() {
		try {
			JSch jsch = new JSch();

			session = jsch.getSession(username, hostname, port);

			if (password != null) {
				session.setPassword(password);
			}
			com.jcraft.jsch.Logger logger = new SettleLogger();
			JSch.setLogger(logger);

			Properties config = new Properties();
			config.put("StrictHostKeyChecking", "no");

			session.setConfig(config);
			// 设置登陆超时时间
			session.connect(15000);

			Channel channel = session.openChannel("sftp");
			channel.connect();

			sftp = (ChannelSftp) channel;
		} catch (JSchException e) {
			e.printStackTrace();
		}
	}

	/**
	 * 关闭连接 server
	 */
	public void logout() {
		if (sftp != null) {
			if (sftp.isConnected()) {
				sftp.disconnect();
			}
		}
		if (session != null) {
			if (session.isConnected()) {
				session.disconnect();
			}
		}
	}

	/**
	 * 将输入流的数据上传到sftp作为文件。文件完整路径=basePath+directory
	 *
	 * @param basePath     服务器的基础路径
	 * @param directory    上传到该目录
	 * @param sftpFileName sftp端文件名
	 * @param input        输入流
	 */
	public void upload(String basePath, String directory, String sftpFileName, InputStream input) throws SftpException {
		try {
			sftp.cd(basePath);
			sftp.cd(directory);
		} catch (SftpException e) {
			// 目录不存在，则创建文件夹
			String[] dirs = directory.split("/");
			String tempPath = basePath;
			for (String dir : dirs) {
				if (null == dir || "".equals(dir)) {
					continue;
				}
				tempPath += "/" + dir;
				try {
					sftp.cd(tempPath);
				} catch (SftpException ex) {
					sftp.mkdir(tempPath);
					sftp.cd(tempPath);
				}
			}
		}
		sftp.put(input, sftpFileName); // 上传文件

	}

	public void deleteFile(String sftpFileName) throws SftpException {
		this.login();
		try {
			this.delete(sftpFileName);
		} catch (Exception e) {
			e.printStackTrace();
		}
		this.logout();
	}
	/**
	 * 删除文件
	 * @param deleteFile 文件名
	 * @throws Exception
	 */
	public  void delete(String deleteFile) throws Exception {
		try {
			sftp.rm(deleteFile);
		} catch (Exception e) {
			throw new Exception(e.getMessage(),e);
		}
	}



	public void uploadFile(String basePath, String directory, String sftpFileName, InputStream input) throws SftpException {
		this.login();
		this.upload(basePath, directory, sftpFileName, input);
		this.logout();
	}

	public void uploadFile(String directory, String sftpFileName, InputStream input) throws SftpException {
		this.uploadFile(defaultRootPath, directory, sftpFileName, input);
	}

	public void uploadFile(String sftpFileName, InputStream input) throws SftpException {
		this.uploadFile("", sftpFileName, input);
	}
	public void uploadFileApp(String directory,String sftpFileName, InputStream input) throws SftpException {
		this.uploadFile(appPath, directory, sftpFileName, input);
	}

	//查询SFTP日志--连接
	class SettleLogger implements com.jcraft.jsch.Logger {
		@Override
		public boolean isEnabled(int level) {
			return true;
		}

		@Override
		public void log(int level, String msg) {
			System.out.println(msg);
		}
	}
}
